package org.apache.ibatis.ibator.maven;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.ibatis.ibator.api.Ibator;
import org.apache.ibatis.ibator.config.IbatorConfiguration;
import org.apache.ibatis.ibator.config.xml.IbatorConfigurationParser;
import org.apache.ibatis.ibator.exception.InvalidConfigurationException;
import org.apache.ibatis.ibator.exception.XMLParserException;
import org.apache.ibatis.ibator.internal.DefaultShellCallback;
import org.apache.ibatis.ibator.internal.util.StringUtility;
import org.apache.ibatis.ibator.internal.util.messages.Messages;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.PropertySet;
/**
 * Says "Hi" to the user.
 * @goal codeGen
 */
public class IbatorMojo extends AbstractMojo {
	private Log log = getLog();

	/**
	 * @parameter
	 */
	private String configfile;
	/**
	 * @parameter
	 */
	private boolean overwrite;
	/**
	 * @parameter
	 */
	private PropertySet propertyset;
	/**
	 * @parameter
	 */
	private boolean verbose;
	/**
	 * @parameter
	 */
	private String contextIds;
	/**
	 * @parameter
	 */
	private String fullyQualifiedTableNames;

	
	public void execute() throws MojoExecutionException, MojoFailureException {
		if (!StringUtility.stringHasValue(configfile)) {
			throw new BuildException(Messages.getString("RuntimeError.0")); //$NON-NLS-1$
		}

		List<String> warnings = new ArrayList<String>();

		File configurationFile = new File(configfile);
		if (!configurationFile.exists()) {
			throw new BuildException(Messages.getString("RuntimeError.1", configfile)); //$NON-NLS-1$
		}

		Set<String> fullyqualifiedTables = new HashSet<String>();
		if (StringUtility.stringHasValue(fullyQualifiedTableNames)) {
			StringTokenizer st = new StringTokenizer(fullyQualifiedTableNames, ","); //$NON-NLS-1$
			while (st.hasMoreTokens()) {
				String s = st.nextToken().trim();
				if (s.length() > 0) {
					fullyqualifiedTables.add(s);
				}
			}
		}

		Set<String> contexts = new HashSet<String>();
		if (StringUtility.stringHasValue(contextIds)) {
			StringTokenizer st = new StringTokenizer(contextIds, ","); //$NON-NLS-1$
			while (st.hasMoreTokens()) {
				String s = st.nextToken().trim();
				if (s.length() > 0) {
					contexts.add(s);
				}
			}
		}

		try {
			Properties p = propertyset == null ? null : propertyset.getProperties();

			IbatorConfigurationParser cp = new IbatorConfigurationParser(p, warnings);
			IbatorConfiguration config = cp.parseIbatorConfiguration(configurationFile);

			DefaultShellCallback callback = new DefaultShellCallback(overwrite);

			Ibator ibator = new Ibator(config, callback, warnings);

			ibator.generate(null, contexts, fullyqualifiedTables);

		} catch (XMLParserException e) {
			for (String error : e.getErrors()) {
				log.equals(error);

			}

			throw new BuildException(e.getMessage());
		} catch (SQLException e) {
			throw new BuildException(e.getMessage());
		} catch (IOException e) {
			throw new BuildException(e.getMessage());
		} catch (InvalidConfigurationException e) {
			for (String error : e.getErrors()) {
				log.equals(error);
			}

			throw new BuildException(e.getMessage());
		} catch (InterruptedException e) {
			// ignore (will never happen with the DefaultShellCallback)
			;
		} catch (Exception e) {
			e.printStackTrace();
			throw new BuildException(e.getMessage());
		}

		for (String error : warnings) {
			log.equals(error);
		}

	}

}
